package org.stvd.common.utils.openim;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.stvd.common.utils.HttpUtil;
import org.stvd.common.utils.StringsUtil;
import org.stvd.core.util.cache.EHCacheUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @Title: OpenImApi
 * @Description: OpenImApi
 * @author zhg5482
 * @date 2022年05月09日
 */
@Component
public class OpenImApi {

    private static volatile OpenImApi instance = null;

    //===================================== 账号体系 ===================================
    private static String USER_REGISTER_URL = "%s/auth/user_register"; //注册新用户
    //===================================== 鉴权相关 ===================================
    private static String TOKEN_REFRESH_URL = "%s/auth/user_token"; //刷新用户token
    //===================================== 群组相关 ===================================
    private static String GROUP_CREATED_URL = "%s/group/create_group"; //创建群组
    private static String GROUP_INVITE_USER_URL = "%s/group/invite_user_to_group"; //邀请进群
    private static String GROUP_KICK_USER_URL = "%s/group/kick_group"; //剔除群聊
    //===================================== 用户相关 ===================================
    private static String USER_REGISTER_CHECK_URL = "%s/manager/account_check"; //查询用户在Im中是否已经注册

    private static String openimApiUrl = ""; //请求地址
    private static String secret = ""; //OpenIM秘钥
    private static int platform; //用户注册的平台类型
    private static int managerPlatform; //管理员平台选择字段Øßßßß
    private static String managerUserId; //管理员userId

    private final static String MANAGER_TOKEN_EXPIRE="manager_token_expire"; //token过期时间
    private final static String MANAGER_TOKEN_VALUE="manager_token_value"; //token值
    private final static String EHCACHE_NANE="openImCache"; //ehcache配置

    @Value("${openim.url}")
    public void setOpenimApiUrl(String openimApiUrl) {
        OpenImApi.openimApiUrl = openimApiUrl;
    }
    @Value("${openim.secret}")
    public void setSecret(String secret) {
        OpenImApi.secret = secret;
    }
    @Value("${openim.platform}")
    public void setPlatform(int platform) {
        OpenImApi.platform = platform;
    }
    @Value("${openim.manager.platform}")
    public void setManagerPlatform(int managerPlatform) {
        OpenImApi.managerPlatform = managerPlatform;
    }
    @Value("${openim.manager.userId}")
    public void setManagerUserId(String managerUserId) {
        OpenImApi.managerUserId = managerUserId;
    }

    private OpenImApi() {}

    /**
     * 运行时加载对象
     */
    public static OpenImApi getInstance() {
        if (instance == null) {
            synchronized(OpenImApi.class){
                 if(instance == null){
                     instance = new OpenImApi();
                 }
            }
        }
        return instance;
    }

    /**
     * 获取请求header
     * @param token 请求token
     * @return headers
     */
    public Map<String, String> headers(String token) {
        HashMap<String, String> header = new HashMap<String, String>();
        header.put("token", token);
        return header;
    }

    /**
     * 注册用户
     * @param userId 用户id
     * @param nickName 用户昵称
     * @param operationId 操作id
     * @return String json串
     */
    public String userRegister(String userId, String nickName, String operationId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("secret", secret);
        paramMap.put("platform", platform);
        paramMap.put("userID", userId);
        paramMap.put("nickname", nickName);
        paramMap.put("operationId", operationId);
        return HttpUtil.sendPost(String.format(USER_REGISTER_URL, openimApiUrl), JSON.toJSONString(paramMap));
    }

    /**
     * 刷新token[换取管理员token]
     * @param userId 用户id 换取管理员token时 管理员userID，此处的userID必须为配置文件config/config.yaml的appManagerUid的其中一个
     * @param operationId 操作id
     * @return String json串
     */
    public String tokenRefresh(String userId, String operationId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("secret", secret);
        paramMap.put("platform", platform); //换取管理员token时 platform=8
        paramMap.put("userID", userId);
        paramMap.put("operationId", operationId);
        return HttpUtil.sendPost(String.format(TOKEN_REFRESH_URL, openimApiUrl), JSON.toJSONString(paramMap));
    }

    /**
     * 换取管理员token
     * @return String
     */
    public String managerToken() {
        EHCacheUtil ehCacheUtil = new EHCacheUtil();
        ehCacheUtil.initCache(EHCACHE_NANE);
        Object expireTime = ehCacheUtil.get(MANAGER_TOKEN_EXPIRE);
        if(expireTime != null ) { //存在
            int expireTimeInt = Integer.valueOf(expireTime.toString());
            String nowTimeMillis = String.valueOf(System.currentTimeMillis());
            String nowTimeM = nowTimeMillis.substring(0, 10);
            int nowTimeInt = Integer.valueOf(nowTimeM);
            if (expireTimeInt > nowTimeInt+60*5) { //如果token 过期或距当前时间还有5分钟过期,则返回token
                Object tokenValue = ehCacheUtil.get(MANAGER_TOKEN_VALUE);
                if (tokenValue != null) {
                    return tokenValue.toString();
                }
            }
        }
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("secret", secret);
        paramMap.put("platform", managerPlatform); //换取管理员token时 platform=8
        paramMap.put("userID", managerUserId);
        paramMap.put("operationId", StringsUtil.getRandomCode(16,"2"));
        String reString = HttpUtil.sendPost(String.format(TOKEN_REFRESH_URL, openimApiUrl), JSON.toJSONString(paramMap));
        if (StringsUtil.isEmpty(reString)) {
           return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(reString);
        int errCode = Integer.valueOf(jsonObject.getString("errCode"));
        if (errCode != 0) { // 获取token失败
            return null;
        }
        String data = jsonObject.getString("data");
        if (StringsUtil.isEmpty(data)) {
            return null;
        }
        JSONObject dataJsonObject = JSONObject.parseObject(data);
        String token = dataJsonObject.getString("token");
        String expireTimeNew = dataJsonObject.getString("expiredTime");
        if (StringsUtil.isEmpty(token) || StringsUtil.isEmpty(expireTimeNew)) {
            return null;
        }
        ehCacheUtil.put(MANAGER_TOKEN_EXPIRE, expireTimeNew);
        ehCacheUtil.put(MANAGER_TOKEN_VALUE, token);
        return token;
    }

    /**
     * 创建群组
     * @param token 请求token
     * @param ownerUserId 群主userId[创建人userId]
     * @param groupName 群组名称
     * @param introduction 群组简介
     * @param operationId 操作id
     * @param memberList 群组人员列表
     * @return String json
     */
    public String groupCreated(String token, String ownerUserId, String groupName, String introduction, String operationId, List<Map<String, Object>> memberList) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("ownerUserID", ownerUserId);
        paramMap.put("groupName", groupName);
        paramMap.put("introduction", introduction);
        paramMap.put("operationID", operationId);
        paramMap.put("memberList", memberList);
        return HttpUtil.sendPost(String.format(GROUP_CREATED_URL, openimApiUrl), headers(token), JSON.toJSONString(paramMap));
    }

    /**
     * 查询当前用户是否已注册
     * @param userId 当前用户账号
     * @return String
     */
    public String checkUserRegister(String userId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        List<String> userList = new ArrayList<String>();
        userList.add(userId);
        paramMap.put("checkUserIDList", userList);
        paramMap.put("operationID", StringsUtil.getRandomCode(16,"2"));
        return HttpUtil.sendPost(String.format(USER_REGISTER_CHECK_URL, openimApiUrl), headers(managerToken()), JSON.toJSONString(paramMap));
    }
}
